package gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.DropMode;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;

import properties.DefaultProperties;
import data.StaticMethods;
import data.Task;
import exceptions.IllegalPatternException;
import exceptions.NoSplitSignException;
import exceptions.VariableDuplicationException;

/**
 * This class provides the window to edit the patterns for renaming a file name.
 * 
 * @author Kevin Wagner
 * @version 1.0
 */
public class EditPatternPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 7804700180454973782L;
	private JLabel fileNameL, inputPatternL, outputPatternL, outputFileNameL;
	private JTextField fileNameTxt, patternInTxt, patternOutTxt, outputTxt;
	private DefaultProperties props;
	private ArrayList<Task> tasks;
	private JButton btnApply, btnRefresh;
	private JList variableList;
	private MainWindow mw;

	/**
	 * Create the frame.
	 * 
	 * @param props
	 *            properties
	 * @param tasks
	 *            the tasks to edit the patterns
	 * @param mw Main window
	 */
	public EditPatternPanel(DefaultProperties props, ArrayList<Task> tasks, MainWindow mw) {
		this.mw=mw;
		this.props = props;
		this.tasks = tasks;
		setBounds(100, 100, 652, 300);

		fileNameL = new JLabel(props.getLocalizedText("fileName"));

		inputPatternL = new JLabel(props.getLocalizedText("patternIn"));

		outputPatternL = new JLabel(props.getLocalizedText("patternOut"));

		outputFileNameL = new JLabel(props.getLocalizedText("output"));

		fileNameTxt = new JTextField(tasks.get(0).getInputFileName());
		fileNameTxt.setColumns(10);
		fileNameTxt.setEnabled(false);

		patternInTxt = new JTextField(tasks.get(0).getInputPattern());
		patternInTxt.setColumns(10);

		patternOutTxt = new JTextField(tasks.get(0).getOutputPattern());
		patternOutTxt.setColumns(10);

		outputTxt = new JTextField(tasks.get(0).getOutputFileName());
		outputTxt.setColumns(10);
		outputTxt.setEnabled(false);

		btnApply = new JButton(props.getLocalizedText("apply"));
		btnApply.addActionListener(this);

		variableList = new JList();
		variableList.setDragEnabled(true);
		variableList.setDropMode(DropMode.INSERT);
		variableList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		JLabel variablesL = new JLabel(props.getLocalizedText("variables"));

		btnRefresh = new JButton(props.getLocalizedText("refresh"));
		btnRefresh.addActionListener(this);

		GroupLayout gl_contentPane = new GroupLayout(this);
		gl_contentPane
				.setHorizontalGroup(gl_contentPane
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_contentPane
										.createSequentialGroup()
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.LEADING)
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addComponent(
																				btnApply)
																		.addPreferredGap(
																				ComponentPlacement.RELATED,
																				442,
																				Short.MAX_VALUE)
																		)
														.addGroup(
																gl_contentPane
																		.createSequentialGroup()
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.TRAILING,
																								false)
																						.addComponent(
																								fileNameL,
																								Alignment.LEADING,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								Short.MAX_VALUE)
																						.addComponent(
																								inputPatternL,
																								Alignment.LEADING,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								Short.MAX_VALUE)
																						.addComponent(
																								outputPatternL,
																								Alignment.LEADING,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								Short.MAX_VALUE)
																						.addComponent(
																								outputFileNameL,
																								Alignment.LEADING,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								Short.MAX_VALUE)
																						.addComponent(
																								variablesL,
																								Alignment.LEADING,
																								GroupLayout.DEFAULT_SIZE,
																								GroupLayout.DEFAULT_SIZE,
																								Short.MAX_VALUE))
																		.addPreferredGap(
																				ComponentPlacement.RELATED)
																		.addGroup(
																				gl_contentPane
																						.createParallelGroup(
																								Alignment.LEADING)
																						.addComponent(
																								btnRefresh)
																						.addGroup(
																								gl_contentPane
																										.createParallelGroup(
																												Alignment.TRAILING)
																										.addComponent(
																												patternOutTxt,
																												Alignment.LEADING)
																										.addComponent(
																												patternInTxt,
																												Alignment.LEADING)
																										.addComponent(
																												fileNameTxt,
																												Alignment.LEADING,
																												GroupLayout.DEFAULT_SIZE,
																												541,
																												Short.MAX_VALUE)
																										.addComponent(
																												outputTxt,
																												Alignment.LEADING,
																												GroupLayout.DEFAULT_SIZE,
																												555,
																												Short.MAX_VALUE)))
																		.addGap(2))
														.addComponent(
																variableList,
																GroupLayout.PREFERRED_SIZE,
																115,
																GroupLayout.PREFERRED_SIZE))
										.addContainerGap()));
		gl_contentPane
				.setVerticalGroup(gl_contentPane
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_contentPane
										.createSequentialGroup()
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(fileNameL)
														.addComponent(
																fileNameTxt,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(
																inputPatternL)
														.addComponent(
																patternInTxt,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(
																outputPatternL)
														.addComponent(
																patternOutTxt,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(
																outputFileNameL)
														.addComponent(
																outputTxt,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(
																variablesL)
														.addComponent(
																btnRefresh))
										.addPreferredGap(
												ComponentPlacement.RELATED)
										.addComponent(variableList,
												GroupLayout.DEFAULT_SIZE, 76,
												Short.MAX_VALUE)
										.addGap(20)
										.addGroup(
												gl_contentPane
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(btnApply)
														)));
		this.setLayout(gl_contentPane);
		this.setVisible(true);
		check();
		parseInput();
	}

	/**
	 * Checks the input tasks for the same input Pattern.
	 */
	private void check() {
		String pattern = tasks.get(0).getInputPattern();
		if (tasks.size() > 1) {
			for (int i = 1; i < tasks.size(); i++) {
				if (!tasks.get(i).getInputPattern().equals(pattern)) {
					JOptionPane.showMessageDialog(this,
							props.getLocalizedText("unequalPatternMessage"),
							props.getLocalizedText("unequalPattern"),
							JOptionPane.ERROR_MESSAGE);
					break;
				}
			}
		}
	}

	private void parseInput() {
		try {
			String[][] result = StaticMethods.parseForward(patternInTxt.getText(),
					fileNameTxt.getText());
			variableList.removeAll();
			String[] data = new String[result.length];
			for (int i = 0; i < result.length; i++) {
				data[i] = result[i][0];
			}
			variableList.setListData(data);
			String output = patternOutTxt.getText();
			for (int i = 0; i < data.length; i++) {
				output = output.replace(result[i][0], result[i][1]);
			}
			outputTxt.setText(output);
		} catch (IllegalPatternException e) {
			JOptionPane.showMessageDialog(this,
					props.getLocalizedText("illegalPatternMessage"),
					props.getLocalizedText("illegalPattern"),
					JOptionPane.ERROR_MESSAGE);
		} catch (NoSplitSignException e) {
			JOptionPane.showMessageDialog(this,
					props.getLocalizedText("NoSplitSignMessage"),
					props.getLocalizedText("NoSplitSign"),
					JOptionPane.ERROR_MESSAGE);
		} catch (VariableDuplicationException e) {
			JOptionPane.showMessageDialog(this,
					props.getLocalizedText("VariableDuplicationMessage"),
					props.getLocalizedText("VariableDuplication"),
					JOptionPane.ERROR_MESSAGE);
		}

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(btnApply)) {
			apply();
		} else if (e.getSource().equals(btnRefresh)) {
			parseInput();
		}

	}

	private void apply() {
		for (int j = 0; j < tasks.size(); j++) {
			Task t = tasks.get(j);
			try {
				String[][] result = StaticMethods.parseForward(patternInTxt.getText(),
						t.getInputFileName());
				t.setInputPattern(patternInTxt.getText());
				t.setOutputPattern(patternOutTxt.getText());
				String output = t.getOutputPattern();
				for (int i = 0; i < result.length; i++) {
					output = output.replace(result[i][0], result[i][1]);
				}
				t.setOutputFileName(output);
			} catch (IllegalPatternException e) {
				JOptionPane.showMessageDialog(this,
						props.getLocalizedText("illegalPatternMessage"),
						props.getLocalizedText("illegalPattern"),
						JOptionPane.ERROR_MESSAGE);
			} catch (NoSplitSignException e) {
				JOptionPane.showMessageDialog(this,
						props.getLocalizedText("NoSplitSignMessage"),
						props.getLocalizedText("NoSplitSign"),
						JOptionPane.ERROR_MESSAGE);
			} catch (VariableDuplicationException e) {
				JOptionPane.showMessageDialog(this,
						props.getLocalizedText("VariableDuplicationMessage"),
						props.getLocalizedText("VariableDuplication"),
						JOptionPane.ERROR_MESSAGE);
			}
		}
		mw.repaintTable();
	}
}
